home *** CD-ROM | disk | FTP | other *** search
- XAcc: Ein universelles Kommunikationsprotokoll für Accessories unter GEM
- ========================================================================
-
- (Version vom 14.5.1989)
-
- [Diese Version enthält eine Änderung der Protokolldefinition gegenüber]
- [älteren Versionen, die die Initialisierungsprozedur betrifft. Näheres]
- [im Abschnitt 'Meldungen der Stufe 0'.]
-
-
-
- GEM AES stellt mit den Funktionen appl_write() und appl_read() eine
- flexible Möglichkeit zur Kommunikation zwischen Accessories und dem
- jeweiligen Hauptprogramm zur Verfügung. In der Praxis entstehen dabei
- jedoch einige Schwierigkeiten:
-
- - appl_write() benötigt die Identifikationsnummer (apid) des Empfängers.
- Diese ist aber nur über appl_find() zu bekommen, wozu der Name des
- jeweiligen Programms angegeben werden muß. Daher können Programme
- nur mit solchen anderen Programmen kommunizieren, deren Namen sie
- kennen. Außerdem hat appl_find() den Fehler, daß ein Hauptprogramm auch
- nach seiner Beendung noch gefunden wird.
-
- - Das Hauptprogramm wird nicht darüber informiert, wann ein Accessory
- aufgerufen oder beendet wird. Dies wäre jedoch oft nützlich, um z.B.
- Änderungen von Systemvariablen, die das Accessory stören könnten,
- vor dem Start eines solchen rückgängig zu machen, oder um dem
- Hauptprogramm eine Gelegenheit zu geben, Änderungen der Systemumgebung
- (z.B. des Clipboards) durch das Accessory festzustellen.
-
- - Es gibt keine genormten Meldungen zum Datenaustausch zwischen Programmen.
-
-
- Das hier vorgestellte Kommunikationsprotokoll löst alle diese Probleme.
- Es wurde für zwei Anwendungsarten konzipiert:
-
- 1. Kommunikation zwischen beliebigen Programmen, die voneinander keine
- Informationen haben, mit elementaren Möglichkeiten zum Datenaustausch.
-
- 2. Kommunikation zwischen einem Hauptprogramm und speziell dazu geschriebenen
- Accessories, die z.B. spezielle Hilfsfunktionen übernehmen. Das einheitliche
- Protokoll stellt sicher, daß Programmkombinationen verschiedener Hersteller
- konfliktfrei verwendet werden können.
-
-
- Dieses Protokoll beruht auf der Tatsache, daß das jeweilige Hauptprogramm
- immer die apid 0 bekommt. Zwar wird diese Eigenschaft nicht in der GEM-
- Dokumentation erwähnt, sie ist jedoch nach Auskunft von Digital Reearch
- in allen GEM-Versionen für MS-DOS und GEMDOS vorhanden. Für die Multitasking-
- Version X/GEM unter FlexOS kann das XAcc-Protokoll allerdings nicht ohne
- Änderungen verwendet werden; dort gibt es aber auch gar keine Accessories.
-
- Eine weitere Voraussetzung ist, daß Programme, die dieses Protokoll nicht
- anwenden, die dazugehörenden Meldungen ignorieren. Jedes ordentliche
- GEM-Programm sollte jedoch unbekannte Meldungen ignorieren, und bis jetzt
- sind auch nur zwei Programme bekannt, die mit diesem Protokoll unverträglich
- sind.
-
-
- Verschiedene Stufen des XAcc-Protokolls:
- ----------------------------------------
-
- Sowohl Accessories als auch Hauptprogramme können sehr verschiedene
- Anforderungen an Kommunikation mit anderen Programmen haben. Um möglichst
- viele Anwendungen zu unterstützen, andererseits aber 'anspruchslose'
- Programme nicht durch ein umfangreiches Protokoll zu kompliziert zu
- machen, gibt es mehrere Stufen des XAcc-Protokolls. Diese Stufen bauen
- aufeinander auf, d.h. ein Programm, das Stufe 2 unterstützt, muß auch
- die Meldungen der Stufen 0 und 1 verstehen. Wenn ein Programm eine bestimmte
- Stufe unterstützt, muß es alle dazugehörenden Meldungen ordnungsgemäß
- bearbeiten.
-
- Bisher sind drei Stufen definiert:
-
- Stufe 0 umfaßt nur die Identifikation, jedoch keinen Datenaustausch. Viele
- Accessories kommen damit aus, insbesondere solche, die nur zur Anwendung mit
- bestimmten Hauptprogrammen gedacht sind und ausschließlich spezielle
- Meldungen benutzen. Aber auch für viele Hauptprogramme ist Stufe 0
- ausreichend.
-
- Stufe 1 umfaßt den Austausch von Textdaten im ASCII-Format. Die meisten
- Hauptprogramme fallen in diese Kategorie, aber auch Accessories, die
- Befehle entgegennehmen und/oder Ergebnisse produzieren.
-
- Stufe 2 umfaßt den Austausch von Grafikdaten in den genormten GEM-Formaten
- für Metafiles und Bitmap-Bildern. Hauptanwender sind natürlich Grafikprogramme
- aller Art, aber auch Textverarbeitungs- und Desktop-Publishing-Programme.
-
- Weitere Stufen sind zur Zeit nicht genormt. Mögliche Datentypen für
- Erweiterungen wären z.B. MIDI-Daten oder Spreadsheet-Daten. Vor der
- Definition weiterer Stufen soll das XAcc-Protokoll erst einmal einige
- Zeit in der Praxis erprobt werden. Dabei wird sich auch der Bedarf für
- weitere Datentypen erkennen lassen.
-
-
- Meldungen im XAcc-Protokoll:
- ----------------------------
-
- Das XAcc-Protokoll unterscheidet zwischen universellen Meldungen, die
- jedes Programm verstehen muß, und speziellen Meldungen, die nur für
- die Kommunikation zwischen bestimmten Programmen gedacht sind. Die
- universellen Meldungen erhalten Nummern von 0x400 bis 0x7FF, die speziellen
- Meldungen Werte ab 0x800. Spezielle Meldungen dürfen nur verschickt werden,
- wenn der Absender anhand der Identifikation des Empfängers erkannt hat, daß
- dieser die Meldung verstehen wird. Im folgenden werden nur noch die
- universellen Meldungen behandelt.
- Darüber hinaus stehen natürlich auch die vom AES definierten Meldungen zur
- Verfügung, wobei insbesondere AC_OPEN und MN_SELECTED sinnvoll eingesetzt
- werden können (MN_SELECTED erfordert natürlich Informationen über den
- Empfänger).
-
-
- Meldungen der Stufe 0:
- ----------------------
-
- ACC_ID = 0x400
- ACC_OPEN = 0x401
- ACC_CLOSE = 0x402
- ACC_ACC = 0x403
-
- Die Kommunikation zwischen Accesories und Hauptprogramm läuft folgendermaßen
- ab:
-
- 1) Beim Start (und bei Beendung) eines Hauptprogramms bekommt jedes Accessory
- vom AES die Meldung AC_CLOSE. Als Reaktion darauf muß es eine Identifikation
- an das Hauptprogramm (apid 0) schicken. Hierfür ist folgendes Format
- definiert:
- msgbuf[0]: ACC_ID
- msgbuf[1]: apid des Absenders
- msgbuf[2]: Länge der Meldung-16, hier also 0
- msgbuf[3]: Versionsnummer und Protokollstufe
- msgbuf[4] und msgbuf[5]: Zeiger auf Namen des Absenders
- msgbuf[6]: Menünummer (menu_id)
- msgbuf[7]: darf nicht verwendet werden (siehe ACC_ACC)
- In msgbuf[3] wird im unteren Byte (msgbuf[3]&0xff) die höchste
- Protokollstufe angegeben, deren Meldungen das Programm versteht. (Dies ist
- unabhängig davon, welche Meldungen das Programm selbst verschickt. Der
- Absender einer Meldung hat sicherzustellen, daß er nur Meldungen abschickt,
- die der Empfänger versteht.) Das obere Byte ist für die Angabe einer
- Versionsnummer in beliebiger Codierung vorgesehen.
- Der Zeiger auf den Namen wird mit dem höchstwertigen Wort zuerst angegeben.
- Der Name ist ein C-String, also eine Folge von Buchstaben mit einem Nullbyte
- am Ende. Um Namenskonflikte zu vermeiden, sollten ausführliche Namen anstatt
- kurzer Buchstabenfolgen verwendet werden. Der Name muß an der angegebenen
- Adresse jederzeit vom Hauptprogramm abfragbar sein, er darf also nicht
- später entfernt werden.
- Die Menünummer ist der von menu_register() zurückgegebene Wert. Accessories
- mit mehreren Menüeinträgen müssen die Meldung ACC_ID mehrmals verschicken.
- Accessories ohne Menüeintrag müssen -1 angeben.
- Auch bei der Initialisierung eines Accessories, also bevor es auf einen
- Aufruf wartet, muß einmal diese Identifikation verschickt werden. Dies ist
- für den Fall notwendig, daß ein XAcc-Hauptprogramm als Auto-Start-Programm
- installiert wird (ab TOS 1.4). Anderenfalls wäre in diesem Fall keine
- Kommunikation möglich.
-
- 2) Als Antwort auf eine ACC_ID-Meldung schickt das Hauptprogramm ebenfalls eine
- Identifikation an das jeweilige Accessory zurück. Diese hat denselben Aufbau
- wie unter 1) beschrieben, lediglich die Menünummer entfällt und kann durch
- einen beliebigen Wert ersetzt werden. Ebenso kann msgbuf[7] für eigene
- Zwecke verwendet werden.
-
- 3) Außerdem reicht das Hauptprogramm Accessory-Identifikationen an alle
- bereits vorher angemeldeten Accessories weiter. Dazu dient die Meldung
- msgbuf[0]: ACC_ACC
- msgbuf[1]: apid des Absenders (also des Hauptprogramms)
- msgbuf[2]: Länge der Meldung-16, abhängig von der Protokollstufe
- msgbuf[3]: Versionsnummer und Protokollstufe des Accessorys
- msgbuf[4] und msgbuf[5]: Zeiger auf Namen des Accessorys
- msgbuf[6]: Menünummer des Accessorys (menu_id)
- msgbuf[7]: apid des Accessorys
-
- 4) Ein Accessory, das die ACC_ACC-Meldung vom Hauptprogramm bekommt, schickt
- eine ACC_ID-Meldung an das so angemeldete Accessory (genau wie an das
- Hauptprogramm).
-
- 5) Wenn ein Accessory aktiv wird (z.B. wenn es im DESK-Menü angeklickt wird
- oder wenn eines seiner Fenster aktiviert wird), schickt es folgende Meldung
- an das Hauptprogramm:
- msgbuf[0]: ACC_OPEN
- msgbuf[1]: apid des Absenders
- msgbuf[2]: Länge der Meldung-16, hier also 0
- Nach Beendigung seiner Aktivitäten (z.B. nach Ausfüllen einer Dialogbox
- oder nach Schließen oder Desaktivierung eines Fensters) schickt es die
- Meldung
- msgbuf[0]: ACC_CLOSE
- msgbuf[1]: apid des Accessorys
- msgbuf[2]: Länge der Meldung-16, hier also 0
- Das Hauptprogramm reagiert auf ACC_OPEN mit einer Restaurierung aller
- veränderten Systemvariablen (soweit möglich und nötig), bei ACC_CLOSE
- kann es den vorherigen Zustand wiederherstellen.
- Auch Accessories sollten Systemvariablen nur nach Versenden von ACC_OPEN
- ändern und vor Versenden von ACC_CLOSE wiederherstellen.
-
- Nach der Initialisierung ist sichergestellt, daß jedes der beteiligten
- Programme die Identität aller anderen erfahren hat, entweder direkt
- durch ACC_ID oder indirekt durch ACC_ACC. Außerdem wird das Hauptprogramm
- über die Aktivierung von Accessories informiert. Eine Meldung über die
- Aktivierung eines Accessory an andere ist meist nicht erforderlich; falls
- dies zur Kommunikation zwischen zwei bestimmten Accessories nötig sein
- sollte, können private Meldungen (ab 0x800) dafür benutzt werden.
-
-
- Meldungen der Stufe 1:
- ----------------------
-
- ACC_ACK = 0x500
- ACC_TEXT = 0x501
- ACC_KEY = 0x502
-
-
- 1) Übermitteln eines Textes:
- msgbuf[0]: ACC_TEXT
- msgbuf[1]: apid des Absenders
- msgbuf[2]: Länge der Meldung-16, hier also 0
- msgbuf[4] und msgbuf[5]: Zeiger auf Text
- Der Text kann alle druckbaren ASCII-Zeichen (Code >= 32) enthalten, ferner
- sind folgende Steuerzeichen definiert:
- 0x09 TAB (kann vom Empfänger auch als Leerzeichen interpretiert werden)
- 0x0A LF (wird vom Empfänger meist ignoriert)
- 0x0D CR (dient als Zeilenendmarkierung)
- Andere Steuerzeichen sollten nur verwendet werden, wenn der Empfänger bekannt
- ist. Der Text wird mit einem Nullbyte abgeschlossen.
- Accessories sollten Texte nur dann verschicken, wenn sie selbst nicht aktiv
- sind, da sonst das Hauptprogramm meist nicht auf den Text reagieren kann
- (die Reaktion erfordert meist eine Bildschirmanzeige, die das Hauptprogramm
- nur ausführen kann, wenn eines seiner Fenster aktiv ist).
- Der Empfänger schickt nach der vollständigen Abarbeitung des Textes als
- Antwort die Meldung
- msgbuf[0]: ACC_ACK
- msgbuf[1]: apid des Absenders (also des Empfängers des Textes)
- msgbuf[2]: Länge der Meldung-16, hier also 0
- msgbuf[3]: 0 wenn der Text ignoriert wurde, 1 wenn eine Aktion erfolgt ist
- Bis zum Eintreffen dieser Meldung darf der Absender des Textes den Text
- nicht verändern und auch keine weiteren Texte verschicken.
- Der Empfänger sollte im Normalfall den Text wie eine Tastatureingabe
- behandeln, ein Textverarbeitungsprogramm sollte ihn z.B. in den Text
- einfügen.
-
- 2) Simulieren eines Tastendrucks:
- msgbuf[0]: ACC_KEY
- msgbuf[1]: apid des Absenders
- msgbuf[2]: Länge der Meldung-16, hier also 0
- msgbuf[3]: Scan-Code der Taste und ASCII-Code (wie von evnt_keybd())
- msgbuf[4]: Status der Shift-Tasten (wie von Kbshift())
- Diese Meldung soll wie ein Keyboard-Event behandelt werden. Auf diese
- Weise können z.B. Steuerbefehle von einem Accessory an das Hauptprogramm
- geschickt werden. Dies setzt allerdings voraus, daß der Empfänger bekannt
- ist, da es keine verbindlichen Konventionen zur Interpretation von
- Tastenbefehlen gibt. Insbesondere ist es dem Empfänger überlassen, ob er
- den Scan-Code oder den ASCII-Code verwendet (oder auch beide).
- Der Empfänger quittiert auch diese Meldung nach ihrer vollständigen
- Bearbeitung mit
- msgbuf[0]: ACC_ACK
- msgbuf[1]: apid des Absenders (also des Empfängers des Textes)
- msgbuf[2]: Länge der Meldung-16, hier also 0
- msgbuf[3]: 0 wenn ACC_KEY ignoriert wurde oder der gegebenen Befehl nicht
- verstanden wurde, 1 wenn eine Aktion erfolgt ist
- Mit dieser Meldung läßt sich z.B. eine Fernsteuerung eines Hauptprogramms
- von einem Accessory aus realisieren.
-
-
- Meldungen der Stufe 2:
- ----------------------
-
- ACC_META = 0x503
- ACC_IMG = 0x504
-
- Diese Meldungen dienen zum Austausch von Bildern. Es werden nur die beiden
- im GEM-Standard definierten Bildformate verwendet, um die verarbeitenden
- Programme nicht zu kompliziert zu machen. Außerdem bieten diese beiden
- Formate genügend Flexibilität, um alle Anforderungen zu erfüllen.
-
- 1) Versenden eines Metafiles:
- msgbuf[0]: ACC_META
- msgbuf[1]: apid des Absenders
- msgbuf[2]: Länge der Meldung-16, hier also 0
- msgbuf[3]: 1 für letzten Teil der Daten, 0 sonst
- msgbuf[4] und msgbuf[5]: Zeiger auf Daten
- msgbuf[6] unf msgbuf[7]: Länge der Daten (32 Bits als Langwort)
- Die Bilddaten werden so versendet, wie sie auch in einer Datei stehen
- könnten. Da die Länge der Daten recht groß werden kann und vor allem
- Accessories als Absender oft nicht genug Speicher haben, um ein ganzes
- Bild zu speichern, kann ein Bild in mehreren Abschnitten versendet werden.
- Der Empfänger muß dann dafür sorgen, daß sie richtig zusammengesetzt
- werden (er kann sie auch in eine Datei schreiben). Der letzte Teil
- eines Bildes wird durch msgbuf[3]=1 gekennzeichnet. Zwischen den einzelnen
- Teilen eines Bildes darf der Absender keine andersartigen Daten an
- denselben Empfänger verschicken. In msgbuf[6] und msgbuf[7] wird jeweils
- die Länge des gerade übertragenen Teils angegeben, nicht die Gesamtlänge.
- Der Empfänger quittiert jeden Bildteil mit ACC_ACK wie bei Stufe 1
- beschrieben.
-
- 2) Versenden eines Bit-Image:
- msgbuf[0]: ACC_IMG
- ansonsten wie unter 1) beschrieben.
-
-
-
- Beispiel für ein einfaches Accessory (in C):
- --------------------------------------------
-
- Die folgenden Auszüge aus einem Accessory zeigen die notwendigen Routinen
- für ein Accessory der Protokollstufe 0:
-
- ...
- #include <portab.h>
- #include <xacc.h>
- ...
-
- send_id(ap_id,menu_id,destination)
- WORD ap_id,menu_id,destination;
- {
- WORD msgbuf[8];
-
- msgbuf[0] = ACC_ID;
- msgbuf[1] = ap_id;
- msgbuf[2] = 0;
- msgbuf[3] = 0x1000; /* Versionsnummer 1.0, Protokollstufe 0*/
- *((char **)(msgbuf+4)) = "Name des Programms";
- msgbuf[6] = menu_id;
- appl_write(destination,16,msgbuf);
- }
-
- main()
- {
- WORD ap_id,menu_id;
- WORD msgbuf[8];
- ...
-
- ap_id = appl_init();
- ...
- menu_id = menu_register(ap_id," ACCESSORY");
- send_id(ap_id,menu_id,0);
- ...
- while (TRUE)
- {
- evnt_mesag(msgbuf);
- switch(msgbuf[0])
- {
- case AC_OPEN:
- msgbuf[0] = ACC_OPEN;
- msgbuf[1] = ap_id;
- msgbuf[2] = 0;
- appl_write(0,16,msgbuf);
- ... /* hier steht die eigentliche Aktivität des Accessorys */
- msgbuf[0] = ACC_CLOSE;
- msgbuf[1] = ap_id;
- msgbuf[2] = 0;
- appl_write(0,16,msgbuf);
- break;
- case AC_CLOSE:
- send_id(ap_id,menu_id,0);
- break;
- case ACC_ACC:
- send_id(ap_id,menu_id,msgbuf[7]);
- break;
- }
- }
- }
-
-
- Auszug aus einem Hauptprogramm der Stufe 0:
- -------------------------------------------
-
- ...
- #include <portab.h>
- #include <xacc.h>
- ...
- #define MAXACCS 6
- WORD acc_cnt = 0;
- WORD acc_apid[MAXACCS];
-
- acc_init(ap_id,acc_id)
- WORD ap_id,acc_id;
- {
- WORD i,msgbuf[8];
-
- if (acc_cnt < MAXACCS)
- {
- acc_apid[acc_cnt] = acc_id;
- msgbuf[0] = ACC_ACC;
- msgbuf[7] = acc_id;
- msgbuf[1] = ap_id;
- msgbuf[2] = 0;
- for (i = 0; i < acc_cnt; i++)
- appl_write(acc_apid[i],16,msgbuf);
-
- msgbuf[0] = ACC_ID;
- msgbuf[3] = 0x2500; /* Version 2.5, Protokollstufe 0 */
- *((char **)(msgbuf+4)) = "Hauptprogrammname";
- msgbuf[6] = 0; /* oder etwas anderes */
- msgbuf[7] = 0; /* oder etwas anderes */
- appl_write(acc_apid[acc_cnt++],16,msgbuf);
- }
- }
-
- main()
- {
- WORD ap_id;
- WORD msgbuf[8];
- ...
- ap_id = appl_init();
- ...
- while (TRUE)
- {
- evnt_mesag(msgbuf);
- switch(msgbuf[0])
- {
- case ACC_ID:
- acc_init(ap_id,msgbuf[1]);
- break;
- case ACC_OPEN:
- /* z.B. Systemvariablen auf 'normale' Werte setzen */
- break;
- case ACC_CLOSE:
- /* z.B. Systemvariablen auf eigene Werte setzen */
- break;
- ...
- }
- ...
- }
- }
-
-
- Programme, die das XAcc-Protokoll verwenden (Stand April 1989):
- ---------------------------------------------------------------
-
- Das Textverarbeitungsprogramm That's Write ist ein Hauptprogramm der
- Stufe 2, es akzeptiert Texte und Bit-Image-Daten. Außerdem kann man
- mit That's Write Texte an Accessories verschicken, indem man den Text
- als Block markiert und das gewünschte Accessory über Tastatur aufruft.
- In diesem Fall erhält das Accessory, falls es mindestens Stufe 1
- versteht, eine ACC_TEXT-Mitteilung, jedoch keine AC_OPEN-Mitteilung.
- Wenn das Accessory den Text nicht verarbeiten kann, oder wenn es nur
- Stufe 0 versteht, wird eine AC_OPEN-Mitteilung verschickt, wie wenn
- kein Block markiert war. So wird sichergestellt, daß das Accessory bei
- einem Aufruf über Tastatur auf jeden Fall aktiviert wird.
-
- Die Adressverwaltung That's Address ist ein Accessory der Stufe 1. Wenn
- sie mit ACC_TEXT aufgerufen wird, interpretiert sie den übergebenen Text
- als Suchwort und gibt die dazugehörende Adresse ebenfalls mit ACC_TEXT
- an das aufrufende Programm zurück. Ebenfalls möglich ist eine manuelle
- Übergabe einer Adresse an das Hauptprogramm, indem That's Address mit
- F5 verlassen wird.
-
- Der TOS-Kommandointepreter ATC-Command ist ein Accessory der Stufe 0.
- In der momentanen Version ist eine Datenübergabe nicht möglich. Spätere
- Versionen werden jedoch Befehle entgegennehmen und Ergebnisse
- zurückgeben.
-
-
- Fragen und Erweiterungsvorschläge bitte richten an:
- ---------------------------------------------------
-
- Konrad Hinsen
- Gelderner Str. 22b
- D-5170 Jülich
-
- Bitnet: CD010HI@DACTH11
- FidoNet: Konrad Hinsen @ 2:242/3.3
- MausNet: Konrad Hinsen @ AC
-